﻿using System.Collections.Generic;
using UnityEngine;
using WorldMapNew;
using XLua;
using Yoozoo.Managers.ResourceManagerV2.Runtime;

namespace WorldMapBase
{
    public class SandBoxNormalMapInfo {
        public string objPath;// 一个节点的meshRenderer可能有多个材质
        public string[] texPaths;
        public Texture[] texs;
        public List<Material> mats;
        public bool bShow;
    }

    /// <summary>
    /// 地图性能
    /// </summary>
    public class WorldPerformance
    {
        private static ResLoader m_resLoader;
        private static Dictionary<string, List<SandBoxNormalMapInfo>> SandBoxNormalMaps;// 预制体 - 材质信息节点
        private static Dictionary<string, bool> SandBoxNormalMapInitState;// 预制体 - 初始化状态
        private static bool bShowNormap = false;
        private static int qualityLevel;
        private static GameObject worldPerformanceRoot;

        public static void LoadSandBoxNormalMap(LuaFunction callBack)
        {
            if (m_resLoader == null) m_resLoader = ResLoader.Alloc();
            string mapPrefabMapPath = "Assets/ResourcesAssets/World/mapdata/sandBoxNormalMaps.asset";
            if (m_resLoader == null)
            {
                m_resLoader = ResLoader.Alloc();
            }
            m_resLoader.Add2Load(mapPrefabMapPath, (bool success, string assetName, object asset) =>
            {
                if (success)
                {
                    InitSandBoxNormalMap(asset);
                    Debug.Log("[沙盘加载] =================== InitSandBoxNormalMap 完成 =================== ");
                }
                if (callBack != null)
                {
                    callBack.Call();
                }
            });
            m_resLoader.Load();
        }

        // 管理沙盘场景中材质性能 主要通过修改shareMat属性
        public static void InitSandBoxNormalMap(object asset)
        {
            SandBoxNormalMaps = new Dictionary<string, List<SandBoxNormalMapInfo>>();
            SandBoxNormalMapInitState = new Dictionary<string, bool>();
            MapNormalMap content = asset as MapNormalMap;
            if (content != null)
            {
                for (int i = 0; i < content.mapNormalMap.Count; i++)
                {
                    NormalData data = content.mapNormalMap[i];
                    string prefabName = data.prefabName;
                    string objPath = data.objPath;
                    string texPaths = data.path;
                    string[] s_texPaths = texPaths.Split('|');
                    SandBoxNormalMapInfo info = new SandBoxNormalMapInfo()
                    {
                        objPath = objPath,
                        texPaths = s_texPaths,
                    };
                    if (!SandBoxNormalMaps.ContainsKey(prefabName))
                    {
                        SandBoxNormalMaps[prefabName] = new List<SandBoxNormalMapInfo>();
                    }
                    var listInfos = SandBoxNormalMaps[prefabName];
                    listInfos.Add(info);
                    SandBoxNormalMaps[prefabName] = listInfos;
                }
                
                //
                worldPerformanceRoot = new GameObject();
                worldPerformanceRoot.name = "[WorldPerformanceRoot]";
            }
        }

        public static void UpdateSandBoxMat(GameObject obj,string objName,bool bIns = false)
        {
            if (obj == null) return;
       
            if (!SandBoxNormalMapInitState.ContainsKey(objName) && SandBoxNormalMaps.ContainsKey(objName)) // 判断当前材质未初始化
            {
                var listInfos = SandBoxNormalMaps[objName];
                for (int i = 0; i < listInfos.Count; i++)
                {
                    var info = listInfos[i];
                    info.mats = new List<Material>();
                    info.texs = new Texture[info.texPaths.Length];
                    Transform tf = obj.transform;
                    if (!string.IsNullOrEmpty(info.objPath))
                    {
                        tf = obj.transform.Find(info.objPath);
                    }
                    if (tf == null) return;
                    MeshRenderer render = tf.GetComponent<MeshRenderer>();
                    if (render)
                    {
                        for (int ii = 0; ii < render.sharedMaterials.Length; ii++)
                        {
                            Material mat = render.sharedMaterials[ii];
                            if (mat && mat.HasProperty("_NormalMap"))
                            {
                                info.mats.Add(mat);
                            }
                        }
                        // 检查性能
                        UpdateSandBoxMatInfo(info);
                    }

                    listInfos[i] = info;
                }
                SandBoxNormalMapInitState[objName] = true;
            }
        }

        private static void UpdateSandBoxMatInfo(SandBoxNormalMapInfo info)
        {
#if UNITY_EDITOR

#else
            if (info.mats == null || info.texPaths == null) return;
            if (info.mats.Count != info.texPaths.Length) return; // 长度不一样 绝壁有问题
            // 检查性能
            if (qualityLevel >= 2)
            {
                if (m_resLoader == null) 
                    m_resLoader = ResLoader.Alloc();
                // 将法线贴图赋值给材质
                for (int i = 0; i < info.mats.Count; i++)
                {
                    var mat = info.mats[i];
                    if (info.texs[i] != null)
                    {
                        mat.SetTexture("_NormalMap", info.texs[i]);
                    }
                    else
                    {
                        string texPath = info.texPaths[i];
                        int texIndex = i;
                        m_resLoader.Add2LoadRapid(texPath, (success, name, asset) =>
                        {
                            if (asset is Texture2D tex)
                            {
                                info.texs[texIndex] = tex;
                                mat.SetTexture("_NormalMap", tex);
                            }
                        });
                    }
                }
                m_resLoader.Load();
            }
            else
            {
                // 去除法线贴图
                for (int i = 0; i < info.mats.Count; i++)
                {
                    info.mats[i].SetTexture("_NormalMap", null);
                }
            }
#endif
        }

        // 更新沙盘材质性能分级
        public static void UpdateSandBoxMatLevel(int quality)
        {
            qualityLevel = quality;
            bool _bShowNormap = qualityLevel >= 2;
            if (bShowNormap != _bShowNormap)
            {
                bShowNormap = _bShowNormap;
                // 修改所有当前性能
                foreach (var objName in SandBoxNormalMaps.Keys)
                {
                    var infos = SandBoxNormalMaps[objName];
                    for (int i = 0; i < infos.Count; i++)
                    {
                        var info = infos[i];
                        UpdateSandBoxMatInfo(info);
                    }
                }
            }
        }

        // 卸载
        public static void Dispose()
        {
            // 置空所有索引
            SandBoxNormalMaps.Clear();
            // 卸载资源加载
            if (m_resLoader != null)
            {
                m_resLoader.Recycle2Cache();
                m_resLoader = null;
            } 
            if(worldPerformanceRoot)
            {
                GameObject.Destroy(worldPerformanceRoot);
                worldPerformanceRoot = null;
            }
        }
    }
}
